'use strict';

/**
 * @Author   fan yang
 * [function("type", "判断引用值和原始值类型")]
 * 1. 分两类 原始值 引用值
 * 2. 区分引用值
 */
__proto__.type = function (target) {
    var typeStr = typeof(target),
        toStr = Object.prototype.toString,
        objStr = {
            "[object Array]" : "array",
            "[object Object]" : "object",
            "[object Number]" : "number - object",
            "[object Boolean]" : "boolean - object",
            "[object String]" : "string - object",
        }
    if (target === null) {
        return "null";
    }else if (typeStr !== "object") {
        return typeStr;
    }else{
        return objStr[toStr.call(target)];
    }
}

/**
 * @Author   fan yang
 * [function("retByteslen", "求字符串的长度")]
 */
__proto__.retByteslen = function (target) {
    var count,
        len;
        count = len = target.length;
    for (var i = 0; i < len; i++) {
        if (target.charCodeAt(i) > 255) {
            count ++;
        }
    }
    return count;
}

/**
 * @Author   fan yang
 * [function("debounce", "网络去抖动")]
 * [param1("hander", "函数")]
 * [param2("delay", "时间")]
 */
__proto__.debounce = function (hander, delay) {
    var timer = null;
    return function() {
        var self = this,
            arg = arguments;
        clearTimeout(timer);

        timer = setTimeout(function() {
            hander.apply(self, arg);
        }, delay);
    }
}

/**
 * @Author   fan yang
 * [function("deepClone", "深层拷贝")]
 * [(1. 遍历对象 for (var prop in obj))]
 * [(2. 判断是不是原始值 typeof() object)]
 * [(3. 判断是数组还是对象 instanceof toString constructor)]
 * [(4. 建立相应的数组或对象)]
 * [(5. 递归)]
 */
__proto__.deepClone = function (origin, target) {
    var target = target || {},
        toStr = Object.prototype.toString,
        arrStr = "[object Array]";

    for (var prop in origin) {
        if (origin.hasOwnProperty(prop)) {
            if (origin[prop] !== "null" && typeof(origin[prop]) == "object") {
                target[prop] = toStr.call(origin[prop]) == arrStr ? [] : {};
                deepClone(origin[prop], target[prop]);
            }else{
                target[prop] = origin[prop];
            }
        }
    }
    return target;
}

/**
 * @Author   fan yang
 * [function("retElementChild", "返回一个节点的子元素")]
 */
__proto__.retElementChild = function (node) {
    var tmp = {
            length : 0,
            push : Array.prototype.push,
            splice : Array.prototype.splice
        },
        child = node.childNodes,
        len = child.length;
    for (var i = 0; i < len; i++) {
        if (child[i].nodeType === 1) {
            tmp.push(child[i]);
        }
    }
    return tmp;
}

/**
 * @Author   fan yang
 * [function("getScrollOffset", "求滚动条滚动距离")]
 */
__proto__.getScrollOffset = function () {
    if (window.pageXOffset) {
        return {
            x : window.pageXOffset,
            y : window.pageYOffset
        }
    }
    return {
        x : document.body.scrollLeft + document.documentElement.scrollLeft,
        y : document.body.scrollTop + document.documentElement.scrollTop
    }
}

/**
 * @Author   fan yang
 * [function("getViewportOffset", "获取可视窗口的大小")]
 */
__proto__.getViewportOffset = function () {
    if (window.innerWidth) {
        return {
            w : window.innerWidth,
            h : window.innerHeight
        }
    }else{
        if (document.compatMode == "BackCompat") {
            return {
                w : document.body.clientWidth,
                h : document.body.clientHeight
            }
        }else{
            return {
                w : document.documentElement.clientWidth,
                h : document.documentElement.clientHeight
            }
        }
    }
}

/**
 * @Author   fan yang
 * [function("createElem", "创建元素")]
 * [param1("elemName", "创建元素节点的名称")]
 * [param2("appendElem", "追加在那个元素里面")]
 * [return("返回创建的元素节点")]
 */
__proto__.createElem = function (elemName, appendElem) {
    if (!elemName) return;

    var elem = document.createElement(elemName); // 创建元素节点
    if (appendElem) {
        appendElem.appendChild(elem);
    }else{
        document.body.appendChild(elem);
    }
    return elem;
}

/**
 * @Author   fan yang
 * [function("removeElem", "删除元素节点")]
 * [param("elemName", "删除元素节点名称")]
 */
__proto__.removeElem = function (elemName) {
    if (!elemName) return;
    elemName.remove();
}

/**
 * @Author   fan yang
 * [function("createStyleSheet", "添加 style")]
 * [param1("cssStr", "css")]
 * [param2("attr", {data-module: mditor})]
 */
__proto__.createStyleSheet = function (cssStr, attr) {
    var styleTag = document.createElement('style');

    attr = attr || {};
    attr.type = "text/css";
    for(var i in attr){
        styleTag.setAttribute(i, attr[i]);
    }

    // IE
    if (styleTag.styleSheet) {
        styleTag.styleSheet.cssText = cssStr;
    } else {
        var tt1 = document.createTextNode(cssStr);
        styleTag.appendChild(tt1);
    }
    return styleTag;
}

/**
 * @Author   fan yang
 * [function("createLink", "添加link")]
 * [param("url", "css地址")]
 */
__proto__.createLink = function (url) {
    var link = document.createElement("link");
    link.setAttribute("rel", "stylesheet");
    link.setAttribute("type", "text/css");
    link.setAttribute("href", url);

    var heads = document.head || document.getElementsByTagName('head')[0]

    heads.appendChild(link);
}

/**
 * @Author   fan yang
 * [function("setStyle", "设置 元素 的 style")]
 * [param1("elem", "给那个元素添加样式")]
 * [param2("style", "样式表")]
 */
__proto__.setStyle = function (elem, style = {}) {
    if (!elem) return;

    for (var val in style) {
        elem.style[val] = style[val];
    }
}

/**
 * @Author   fan yang
 * [function("getStyle", "获取元素的属性值 getComputedStyle",
 *           "getComputedStyle 的第二个参数 是获取伪元素的样式表")]
 * [param1("obj elem", "元素")]
 * [param2("str prop", "样式属性名 eg: width")]
 * [return("返回属性值")]
 */
__proto__.getStyle = function (elem, prop) {
    if (window.getComputedStyle) {
        return window.getComputedStyle(elem, null)[prop];
    }else{
        return elem.currentStyle[prop];
    }
}

/**
 * @Author   fan yang
 * [function("addEvent", "封装事件处理函数 解决兼容性问题")]
 * [param1("obj elem", "绑定在谁身上")]
 * [param2("str type", "事件类型")]
 * [param3("fun handle", "事件处理函数")]
 */
__proto__.addEvent = function (elem, type, handle) {
    if (elem.addEventListener) {
        elem.addEventListener(type, handle, false);
    }else if(elem.attachEvent) {
        elem.attachEvent('on' + type, handle);
    }else{
        elem['on' + type] = handle;
    }
}

/**
 * @Author   fan yang
 * [function("removeEvent", "移除事件处理函数")]
 * [param1("obj elem", "绑定在谁身上")]
 * [param2("str type", "事件类型")]
 * [param3("fun handle", "事件处理函数")]
 */
__proto__.removeEvent = function (elem, type, handle) {
    if (elem.removeEventListener) {
        elem.removeEventListener(type, handle, false);
    }else{
        elem.attachEvent('on' + type, handle);
    }
}

/**
 * @Author   fan yang
 * [function("stopBubble", "阻止事件冒泡")]
 * #[param1("event", "事件对象")]
 */
__proto__.stopBubble = function (event) {
    if (event.stopPropagation) {
        event.stopPropagation();
    }else{
        event.cancelBubble();
    }
}

/**
 * @Author   fan yang
 * [function("cancelHandler", "阻止默认事件")]
 * [param1("event", "事件对象")]
 */
__proto__.cancelHandler = function (event) {
    if (event.preventDefault) {
        event.preventDefault();
    }else{
        event.returnValue = false;
    }
}

/**
 * @Author   fan yang
 * [function("drag", "拖拽元素")]
 * [param1("event", "要拖拽元素")]
 */
__proto__.drag = function (elem) {
    var dis_x,
        dis_y;
    addEvent(elem, 'mousedown', function(e) {
        var event = e || window.event;
        dis_x = event.clientX - parseInt(getStyle(elem, 'left'));
        dis_y = event.clientY - parseInt(getStyle(elem, 'top'));
        addEvent(document, 'mousemove', mouseMove);
        addEvent(document, 'mouseup', mouseUp);
        stopBubble(event);
        cancelHandler(event);
    });
    function mouseMove(e) {
        var event = e || window.event;
        elem.style.left = event.clientX - dis_x + 'px';
        elem.style.top = event.clientY - dis_y + 'px';
    }
    function mouseUp(e) {
        var event = e || window.event;
        removeEvent(document, 'mousemove', mouseMove);
        removeEvent(document, 'mouseup', mouseUp);
    }
}
